import { Custom, FormItem, CustomEnum } from 'custom/index'
import { FormItemOption } from 'custom/custom/FormItem'
import { F } from '@/utils/form-item'
import { Component } from 'vue';

import axios from 'axios'
// 查询单个字典， 这里引用http会出现循环引用，很烦
function getDict(dictNo: string): Promise<any[]> {
  return axios({
    method: 'POST',
    baseURL: import.meta.env.VITE_APP_API_BASE_URL,
    headers: { token: localStorage.getItem('token') },
    url: '/ykf/dictDetail/listByNo',
    data: { dictNo }
  }).then(res => res.data.data)
}

interface SelectOptions {
  value: string | number | boolean;
  label: string | number;
  disabled?: boolean
}

export default class Form<T extends FormItem = FormItem> extends Custom {
  public static name: CustomEnum = 'Form';

  // 基础的添加表单组件，可以被复写
  public useItem(name: string | FormItemOption): T {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    const item = new FormItem(option.prop || 'FormItem') as T
    return item
  }
  public addItem(name: string | FormItemOption) {
    this.useItem(name)
    return this
  }

  // 添加自定义组件
  public useCustomItem(tag: Component, name: string | FormItemOption ) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    option.tag = tag
    return this.useItem(option)
  }
  public addCustomItem(tag: Component, name: string | FormItemOption ) {
    this.useCustomItem(tag, name)
    return this
  }

  // 添加范围组件
  public useRangeItem(option: FormItemOption<string[]>) {
    const { prop = [] } = option
    const item  = new FormItem(prop[0] || 'FormItem')
    return item
  }
  public addRangeItem(option: FormItemOption<string[]>) {
    this.useRangeItem(option)
    return this
  }

  // 添加自定义范围组件
  public useCustomRangeItem(tag: Component, option: FormItemOption<string[]>) {
    const o = Object.assign({ tag }, option)
    return this.useRangeItem(o)
  }
  public addCustomRangeItem(tag: Component, option: FormItemOption<string[]>) {
    this.useCustomRangeItem(tag, option)
    return this
  }

  // 添加日期选择器
  public useDatePicker(name: string | FormItemOption) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    return this.useItem(F.datePicker(option))
  }
  public addDatePicker(name: string | FormItemOption) {
    this.useDatePicker(name)
    return this
  }

  // 添加日期范围选择器
  public useDateRangePicker(props: [string, string], option: FormItemOption<string[]> = {}) {
    const modelLabel = ['startDate', 'endDate']
    const defaultValue = ['', '']
    return this.useRangeItem(F.dateRangePicker({
      prop: props,
      modelLabel: modelLabel,
      default: defaultValue,
      ...option
    }))
  }
  public addDateRangePicker(props: [string, string], option: FormItemOption<string[]> = {}) {
    this.useDateRangePicker(props, option)
    return this
  }

  // 添加时间选择器
  public useDateTimePicker(name: string | FormItemOption) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    return this.useItem(F.dateTimePicker(option))
  }
  public addDateTimePicker(name: string | FormItemOption) {
    this.useDateTimePicker(name)
    return this
  }

  // 添加时间范围选择
  public useDateTimeRangePicker(props: [string, string], option: FormItemOption<string[]> = {}) {
    const modelLabel = ['startDate', 'endDate']
    const defaultValue = ['', '']
    return this.useRangeItem(F.dateTimeRangePicker({
      prop: props,
      modelLabel: modelLabel,
      default: defaultValue,
      ...option
    }))
  }
  public addDateTimeRangePicker(props: [string, string], option: FormItemOption<string[]> = {}) {
    this.useDateTimeRangePicker(props, option)
    return this
  }

  // 数字范围选择器
  public useNumberRangePicker(props: [string, string], option: FormItemOption<string[]> = {}) {
    const modelLabel = ['start', 'end']
    return this.useRangeItem(F.numberRangePicker({
      prop: props,
      modelLabel: modelLabel,
      ...option
    }))
  }
  public addNumberRangePicker(props: [string, string], option: FormItemOption<string[]> = {}) {
    this.useNumberRangePicker(props, option)
    return this
  }

  // 添加固定选项的select
  public useSelect(name: string | FormItemOption, options: SelectOptions[] = []) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    return this.useItem(F.optionSelect(Object.assign({ options, clearable: true, placeholder: '' }, option)))
  }
  public addSelect(name: string | FormItemOption, options: SelectOptions[] = []) {
    this.useSelect(name, options)
    return this
  }

  // 添加获取远程接口的select
  public useApiSelect(name: string | FormItemOption, api: (data?: any) => Promise<SelectOptions[]>) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    return this.useItem(F.apiSelect(Object.assign({ api, clearable: true, placeholder: '' }, option)))
  }
  public addApiSelect(name: string | FormItemOption, api: (data?: any) => Promise<SelectOptions[]>) {
    this.useApiSelect(name, api)
    return this
  }

  // 添加字典选择
  public useDictSelect(name: string | FormItemOption, dictNo: string) {
    const api = () => getDict(dictNo)
    return this.useApiSelect(name, api).setProp('valueKey', 'val').setProp('labelKey', 'name')
  }
  public addDictSelect(name: string | FormItemOption, dictNo: string) {
    this.useDictSelect(name,  dictNo)
    return this
  }

  // 单选
  public useRadio(name: string | FormItemOption, options: SelectOptions[] = []) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    return this.useItem(F.optionRadio(Object.assign({ options, clearable: true, placeholder: '' }, option)))
  }
  public addRadio(name: string | FormItemOption, options: SelectOptions[] = []) {
    this.useRadio(name, options)
    return this
  }

  // 评分
  public useRate(name: string | FormItemOption) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    return this.useItem(F.rateItem(Object.assign({}, option)))
  }
  public addRate(name: string | FormItemOption) {
    this.useRate(name)
    return this
  }

  // 上传图片
  public useUploadImage(name: string | FormItemOption) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    return this.useItem(F.uploadImage(Object.assign({}, option)))
  }

  // 选择城市
  public useCityPicker(name: string | FormItemOption) {
    const option: FormItemOption = typeof name === 'string' ? { prop: name } : name
    return this.useItem(F.cityPicker(Object.assign({}, option)))
  }
}
